use quote::quote;
use syn::{parse::Parse, punctuated::Punctuated, MetaNameValue, Token};
use syn::{Expr, Lit};
use crate::utils;

pub struct ResponseAttr {
    pub entries: Punctuated<MetaNameValue, Token![,]>,
}

impl ResponseAttr {
    pub fn extract_filed(&self, status_code: &mut u16, content_type: &mut proc_macro2::TokenStream) -> Result<(), proc_macro2::TokenStream> {
        let aqua = utils::get_aqua_path();

        for entry in self.entries.iter() {
            // entry.path is key(like status or content_type)
            // entry.value is value 
            let ident = entry.path.get_ident().map(|id| id.to_string());
            match (ident.as_deref(), &entry.value) {
                (Some("status"), Expr::Lit(lit_expr)) => {
                    if let Lit::Int(val) = &lit_expr.lit {
                        *status_code = val.base10_parse().unwrap();
                    }
                }
                (Some("content_type"), Expr::Lit(lit_expr)) => {
                    if let Lit::Str(val) = &lit_expr.lit {
                        match val.value().as_str() {
                            "json" => *content_type = quote! { #aqua::http::HttpContentType::ApplicationJson },
                            "text" => *content_type = quote! { #aqua::http::HttpContentType::TextPlain },
                            other => return Err(syn::Error::new_spanned(
                                lit_expr,
                                format!("unsupported content_type: {}", other)
                            )
                            .to_compile_error())
                        }
                    }
                }
                _ => {}
            }
        }
        Ok(())
    }
}

impl Parse for ResponseAttr {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        Ok(ResponseAttr {
            entries: Punctuated::parse_terminated(input)?,
        })
    }
}